#include "tradeserver.h"
#include "Main/global.h"
#include <QCryptographicHash>
#include <QDebug>
#include "Main/constant.h"
#include "Msg/Rsp/rspbase.h"
#include "Msg/msgbase.h"
#include "Msg/HashtableMsg.h"

TradeServer::TradeServer()
{
    m_nCurSevPos = 0;
}

void TradeServer::InitServerAddr(HashtableMsg htm_server_list)
{
    m_server_list = htm_server_list;
}

bool TradeServer::Login(const QString qsUser, const QString qsPwd, QString& qsErrMsg)
{
    QString qsIP;
    int nPort;
    if (!GetNetAddress(qsIP, nPort))
        return false;
//    qsIP = "127.0.0.1";
//    nPort = 15901;
    m_comClient.Init(qsIP, nPort);

    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "8001");
//    sprintf(Global::Instance()->gReqHead.user_id,"%s", qsUser.toStdString().c_str());

    QString md5;
    QByteArray bb;
    bb = QCryptographicHash::hash(qsPwd.toLatin1(), QCryptographicHash::Md5 );
    md5.append(bb.toHex());
    qDebug()<< "md5:"<< md5;
    MsgBase req8001;
    req8001.AddPara("user_id_type", 1);
    req8001.AddPara("oper_flag", 1);
    req8001.AddPara("user_type", gc_sUserTypeOper.c_str());
    req8001.AddPara("user_id", qsUser);
    req8001.AddPara("user_pwd", md5);
    req8001.AddPara("login_ip", Global::Instance()->GetHostIpAddress());
    req8001.AddPara("login_server_code", Global::Instance()->GetServerList().GetQString(0, "server_code"));
    req8001.AddPara("is_down_para", "0");
    req8001.AddPara("ver_num", "3.0.0");
    std::string sRsp;// = m_req8006.ToString();
//    m_comClient.TransForNormal(req8001.ToString(), sRsp, qsErrMsg);
//    std::string sTest = "#oper_flag=1#user_type=1#user_id_type=1#user_id=ylink1#user_pwd=4297f44b13955235245b2497399d7a93#login_ip=172.168.65.229#ver_num=3.0.0#is_down_para=0#login_server_code=M001#";

    PACKET_INFO pktInfo(CHANNEL_TRADE);

    int nRet = m_comClient.TransForNormal(pktInfo, req8001.ToString(), sRsp, qsErrMsg);
    if (nRet != E_TRANS_SUCCESS)
    {
        if (++m_nCurSevPos >= m_server_list.size())
            m_nCurSevPos = 0;
        return false;
    }

    HEADER_RSP rspHead;
    rspHead.DecodeRspHead(sRsp.c_str());
    qDebug()<< "响应8001:"<< QString::fromStdString(sRsp);
    if ( 0 == gc_ErrCodeSus.compare(rspHead.rsp_code))
    {
        RspBase rspMsg;
        rspMsg.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
        Global::Instance()->m_bLogSuccess = true;
        Global::Instance()->m_qsLockKey = qsPwd;
        Global::Instance()->SetLoginRsp(rspMsg);
        sprintf(Global::Instance()->gReqHead.branch_id,"%s", rspMsg.GetQStringPara("branch_id").toStdString().c_str());
        RequestBranchInfo();
        return true;
    }
    return false;
}

bool TradeServer::RequestBranchInfo()
{
     MsgBase req;
     req.AddPara("oper_flag", 1);
     sprintf(Global::Instance()->gReqHead.exch_code,"%s", "9010");
     std::string sRsp;
     QString qsErrMsg;
     bool bRet = TransForNormal(req.ToString(), sRsp, qsErrMsg);
     RspBase rspMsg;
     rspMsg.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
     if (bRet)
     {
         HashtableMsg htm;
         htm.Parse(rspMsg.GetQStringPara("htm_branch_info"));
         int nCount = htm.size();
         if (nCount > 0)
         {
             m_mapBranch.clear();
             for (auto it = 0; it < nCount; it++)
             {
                 BranchInfo branch;
                 branch.branch_id = htm.GetQString(it, "branch_id");
                 branch.branch_name = htm.GetQString(it, "branch_name");
                 branch.branch_level = htm.GetQString(it, "branch_level");
                 branch.p_branch_id = htm.GetQString(it, "parent_branch_id");
                 m_mapBranch[branch.branch_id] = branch;
             }
         }
     }

     return bRet;
}

ComboData* TradeServer::GetMyBranchs()
{
    if (m_mapBranch.size() == 0)
        RequestBranchInfo();

    ComboData* pModel = new ComboData;
    auto it  =  m_mapBranch.begin();
    QString branchId = Global::Instance()->GetParaFrom8001("branch_id");
//    QStringList qsBranchs;
    pModel->AddData(QPair<QString,QString>("["+branchId+"]"+Global::Instance()->GetParaFrom8001("branch_name"),branchId));
    while (it != m_mapBranch.end())
    {
        if(it.value().p_branch_id == branchId)
        {
            pModel->AddData(QPair<QString,QString>("["+it.value().branch_id+"]"+it.value().branch_name, it.value().branch_id));
        }
//test 增加孙子显示
        auto father = m_mapBranch.find(it.value().p_branch_id);
        if (father != m_mapBranch.end())
        {
            auto grand = m_mapBranch.find(father.value().p_branch_id);
            if (grand != m_mapBranch.end() && grand.value().branch_id == branchId)
                pModel->AddData(QPair<QString,QString>("["+it.value().branch_id+"]"+it.value().branch_name, it.value().branch_id));
        }
        it++;
    }

//    qDebug()<<"GetMyBranchs:"<<qsBranchs;
    return pModel;
}

void TradeServer::GetGradeInfo()
{
    MsgBase req;
    req.AddPara("oper_flag", 1);
    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "9025");
    std::string sRsp;
    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString(), sRsp, qsErrMsg);
    RspBase rspMsg;
    rspMsg.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    HashtableMsg htm;
    htm.Parse(rspMsg.GetQStringPara("htm_result"));
    //#htm_result=is_fast｜branch_id｜host_grade_id_s｜sub_can_use｜grade_name｜m_fare_model_id｜b_fare_model_id｜grade_desc｜bank_no｜grade_id｜acct_type｜
    int nCount = htm.size();
    if (nCount > 0)
    {
        m_lAllCustGrade.clear();
        for (auto it = 0; it < nCount; it++)
        {
            CustGrade grade;
            grade.branch_id = htm.GetQString(it, "branch_id");
            grade.grade_name = htm.GetQString(it, "grade_name");
            grade.grade_id = htm.GetQString(it, "grade_id");
            qDebug()<<" grade_name "<<grade.grade_name<<" grade_id"<<grade.grade_id;

            m_lAllCustGrade.push_back(grade);
        }
    }

    qDebug()<<"request CustGrade size:"<<m_lAllCustGrade.size();
}

void TradeServer::GetProdCode()
{
    MsgBase req;
    req.AddPara("oper_flag", 1);
    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "1002");
    std::string sRsp;
    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString(), sRsp, qsErrMsg);
    RspBase rspMsg;
    rspMsg.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    m_htm_prod_code.Parse(rspMsg.GetQStringPara("htm_prod_code"));
    qDebug()<<"request ProdCode size："<<m_htm_prod_code.size();
    //#htm_prod_code=market_id｜upper_limit_value｜exch_unit｜prod_group_name｜prod_group_id｜tick｜variety_type｜lower_limit_value｜prod_name｜prod_code｜measure_unit｜variety_id｜active_flag
}
//如果返回QStringListModel* qml报ReferenceError: modelData is not defined
QStringList TradeServer::GetSomeProdCode(const QStringList qsMarketList)
{
    if (m_htm_prod_code.size() == 0)
        GetProdCode();

    QStringList listCodes;
//    QStringListModel* pModel = new QStringListModel;
    for(int i = 0; i < m_htm_prod_code.size(); ++i)
    {
        for (int k = 0; k < qsMarketList.size(); ++k)
        {
            if (qsMarketList.at(k) ==  m_htm_prod_code.GetQString(i,"market_id"))
                listCodes.append(m_htm_prod_code.GetQString(i,"prod_code"));
        }
    }

//    pModel->setStringList(listCodes);
    qDebug()<<"GetSomeProdCode result "<<listCodes;
    return listCodes;
}

ComboData *TradeServer::GetCustGradeByBranchs(const QString qsBranchId,bool bAll)
{
    if (m_lAllCustGrade.size() == 0)
        GetGradeInfo();

    QList<CustGrade> grades;
    auto it = m_mapBranchCustGrade.find(qsBranchId);
    if (it != m_mapBranchCustGrade.end())
    {
       grades  = it.value();
    }
    else
    {
        for (int i = 0; i < m_lAllCustGrade.size(); ++i)
        {
            if (m_lAllCustGrade[i].branch_id == qsBranchId || qsBranchId.isEmpty())
                grades.push_back(m_lAllCustGrade[i]);
        }
        m_mapBranchCustGrade[qsBranchId] = grades;
    }

    ComboData* pModel = new ComboData;

    if (bAll)
        pModel->AddData(QPair<QString,QString>(" ", "null"));//参数2不能使用空格，否则其它项显示空白
//    pModel->AddData(QPair<QString,QString>("["+qsBranchId+"]"+Global::Instance()->GetParaFrom8001("branch_name"),qsBranchId));
    for (int i = 0; i < grades.size();++i)
    {
        qDebug()<<"add grade "<<grades[i].grade_name;
        pModel->AddData(QPair<QString,QString>(grades[i].grade_name,grades[i].grade_id));
    }

    qDebug()<<"qsBranchId:"<<qsBranchId<<" CustGrade size:"<<grades.size();
    return pModel;
}

bool TradeServer::QueryForceOrder(QString &tipInfo,RspInterface *pRsp, const QString reqInfo)
{
    MsgBase req;
    req.AddPara("oper_flag", 1);

    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "3069");
    std::string sRsp;
//    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString()+reqInfo.toStdString(), sRsp, tipInfo);
    pRsp->m_rsp.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    if (bRet)
    {
        ArrayListMsg alm;
        alm.Parse(pRsp->m_rsp.GetQStringPara("alm_result"));
        pRsp->m_alms["alm_result"] = alm;
    }
    return bRet;
}

bool TradeServer::QueryRiskCustCount(QString &tipInfo, RspInterface *pRsp, const QString reqInfo)
{
    MsgBase req;
    req.AddPara("oper_flag", 1);

    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "3095");
    std::string sRsp;
//    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString()+reqInfo.toStdString(), sRsp, tipInfo);
    pRsp->m_rsp.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    if (bRet)
    {
        ArrayListMsg alm;
        alm.Parse(pRsp->m_rsp.GetQStringPara("risk_dist"));
        pRsp->m_alms["risk_dist"] = alm;
    }
    return bRet;
}

bool TradeServer::QueryAgentRiskCustCount(QString &tipInfo, RspInterface *pRsp, const QString reqInfo)
{
    MsgBase req;
    req.AddPara("oper_flag", 0);

    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "3096");
    std::string sRsp;
//    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString()+reqInfo.toLocal8Bit().toStdString(), sRsp, tipInfo);
    pRsp->m_rsp.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    if (bRet)
    {
        ArrayListMsg alm;
        alm.Parse(pRsp->m_rsp.GetQStringPara("branch_id"));
        pRsp->m_alms["branch_id"] = alm;
    }
    return bRet;
}

bool TradeServer::QueryHisRiskCustList(QString &tipInfo, RspInterface *pRsp, const QString reqInfo)
{
    MsgBase req;
    req.AddPara("oper_flag", 0);

    sprintf(Global::Instance()->gReqHead.exch_code,"%s", "3094");
    std::string sRsp;
//    QString qsErrMsg;
    bool bRet = TransForNormal(req.ToString()+reqInfo.toLocal8Bit().toStdString(), sRsp, tipInfo);
    pRsp->m_rsp.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    if (bRet)
    {
        ArrayListMsg alm;
        alm.Parse(pRsp->m_rsp.GetQStringPara("risk_cust"));
        pRsp->m_alms["risk_cust"] = alm;
    }
    return bRet;
}

QString TradeServer::GetCustGradeName(const QString qsID)
{
    for (int i = 0; i < m_lAllCustGrade.size(); ++i)
    {
        if (m_lAllCustGrade[i].grade_id == qsID)
            return m_lAllCustGrade[i].grade_name;
    }

    return "";
}

QString TradeServer::GetBranchName(const QString qsID)
{
    auto it = m_mapBranch.find(qsID);
    if (it != m_mapBranch.end())
        return it.value().branch_name;

    return "";
}

QString TradeServer::GetBranchID(const QString qsName)
{
    auto it = m_mapBranch.begin();
    while (it != m_mapBranch.end())
    {
        if (it.value().branch_name == qsName)
            return it.key();
        it++;
    }

    return "";
}

bool TradeServer::GetNetAddress(QString &qsIP, int &nPort)
{
    if (m_server_list.size() == 0)
        return false;
    qsIP = m_server_list.GetQString(m_nCurSevPos, "trans_ip");
    nPort = m_server_list.GetQString(m_nCurSevPos, "trans_port").toInt();
    qDebug()<<"交易："<<qsIP<<":"<<nPort;
    return true;
}

bool TradeServer::TransForNormal(const std::string &sReq, std::string &sRsp, QString &qsErrMsg)
{
    QString qsIP;
    int nPort;
    if (!GetNetAddress(qsIP, nPort))
        return false;

    m_comClient.Init(qsIP, nPort);
    PACKET_INFO pktInfo(CHANNEL_TRADE);
//    pktInfo.nEncr = 0;
    sprintf(Global::Instance()->gReqHead.term_type,"%s",gc_sTermTypeManage.c_str());

    int nRet = m_comClient.TransForNormal(pktInfo, sReq, sRsp, qsErrMsg);
    if (nRet != E_TRANS_SUCCESS)
    {
        if (++m_nCurSevPos >= m_server_list.size())
            m_nCurSevPos = 0;
        return false;
    }

    HEADER_RSP rspHead;
    rspHead.DecodeRspHead(sRsp.c_str());
//    qDebug()<< "响应Risk:"<< QString::fromStdString(sRsp);
    if ( 0 == gc_ErrCodeSus.compare(rspHead.rsp_code))
    {
        qsErrMsg = "";
        return true;
    }

    RspBase rspMsg;
    rspMsg.ParseRspBody(QString::fromLocal8Bit(sRsp.c_str()));
    qsErrMsg = rspMsg.GetQStringPara("rsp_msg");
    qDebug()<<"qsErrMsg:"<<qsErrMsg;
    return false;
}
